home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / mtools.lha / mtools-2.0.7 / file_write.c < prev    next >
C/C++ Source or Header  |  1992-09-10  |  2KB  |  121 lines

  1. #include <stdio.h>
  2. #include "msdos.h"
  3.  
  4. extern int full, fat_error, clus_size, dir_start, dir_len;
  5. extern unsigned end_fat;
  6.  
  7. static int need_nl, put_cluster();
  8.  
  9. /*
  10.  * Write out clusters with input from the given file pointer.   Returns the
  11.  * size of the file (which may have changed) or -1 on error.
  12.  */
  13.  
  14. long
  15. file_write(fp, firstfat, filesize, textmode)
  16. FILE *fp;
  17. unsigned int firstfat;
  18. long filesize;
  19. int textmode;
  20. {
  21.     int i;
  22.     unsigned int fat, oldfat, next_fat();
  23.     long size;
  24.  
  25.     oldfat = 0;
  26.     fat = firstfat;
  27.     need_nl = 0;
  28.     size = 0L;
  29.  
  30.     /* CONSTCOND */
  31.     while (1) {
  32.         if ((i = put_cluster(fp, fat, &filesize, textmode)) < 0) {
  33.             if (oldfat) {
  34.                 fat_encode(oldfat, end_fat);
  35.                 if (fat_free(firstfat))
  36.                     fat_error++;
  37.                 full = 1;
  38.             }
  39.             return(-1);
  40.         }
  41.  
  42.         size += i;
  43.         if (size >= filesize) {
  44.             fat_encode(fat, end_fat);
  45.             break;
  46.         }
  47.         oldfat = fat;
  48.                     /* get next free cluster */
  49.         fat = next_fat(oldfat);
  50.         if (fat == 1) {
  51.             fat_encode(oldfat, end_fat);
  52.                     /* delete it, if doesn't fit */
  53.             if (fat_free(firstfat))
  54.                 fat_error++;
  55.             full = 1;
  56.             return(-1);
  57.         }
  58.         fat_encode(oldfat, fat);
  59.     }
  60.     return(size);
  61. }
  62.  
  63. /*
  64.  * Write to the cluster from the named Unix file descriptor.  Returns the
  65.  * size of what was written, or -1 on error.
  66.  */
  67.  
  68. static int
  69. put_cluster(fp, num, filesize, textmode)
  70. FILE *fp;
  71. unsigned int num;
  72. long *filesize;
  73. int textmode;
  74. {
  75.     int i, buflen, c;
  76.     long start;
  77.     unsigned char tbuf[MAX_CLUSTER];
  78.     void disk_write(), perror();
  79.  
  80.     start = (long) (num - 2) * clus_size + dir_start + dir_len;
  81.     buflen = clus_size * MSECTOR_SIZE;
  82.                     /* '\n' to '\r\n' translation */
  83.     if (textmode) {
  84.         i = 0;
  85.         if (need_nl) {
  86.             tbuf[i++] = '\n';
  87.             need_nl = 0;
  88.         }
  89.         while (i < buflen) {
  90.             if ((c = fgetc(fp)) == EOF) {
  91.                     /* put a file EOF marker */
  92.                 tbuf[i++] = 0x1a;
  93.                     /* make the file appear larger */
  94.                 *filesize = *filesize + 1;
  95.                 break;
  96.             }
  97.             if (c == '\n') {
  98.                 tbuf[i++] = '\r';
  99.                     /* make the file appear larger */
  100.                 *filesize = *filesize + 1;
  101.                     /* if at the end of the buffer */
  102.                 if (i == buflen) {
  103.                     need_nl++;
  104.                     break;
  105.                 }
  106.             }
  107.             tbuf[i++] = (unsigned char) c;
  108.         }
  109.     }
  110.                     /* much easier.... */
  111.     else {
  112.         if ((i = fread((char *) tbuf, sizeof(*tbuf), buflen, fp)) <= 0) {
  113.             perror("put_cluster: fread");
  114.             return(-1);
  115.         }
  116.     }
  117.  
  118.     disk_write(start, tbuf, buflen);
  119.     return(i);
  120. }
  121.